package ru.fizteh.fivt.demo.calc;

//import ru.fizteh.fivt.demo.*;
//import ru.fizteh.fivt.demo.calc.*;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

import ru.fizteh.fivt.demo.ntypes.MyNumber;
import ru.fizteh.fivt.demo.ntypes.MyNumberFloat;
import ru.fizteh.fivt.demo.ntypes.MyNumberString;
import ru.isa.dcs.vvvol.util.consoleMenu.Action;
import ru.isa.dcs.vvvol.util.consoleMenu.Item;
import ru.isa.dcs.vvvol.util.consoleMenu.Menu;
import Ice.Identity;
import Ice.Logger;

public class IceServer4CalcNumber extends Ice.Application {

	// Ice Communicator & Object adapter
	static Ice.Communicator comm;
	static Ice.ObjectAdapter adapter;

	// Ice logger
	static Logger log;
	
	// CalcNumberServer name
	static String SERVER_APP_NAME = "Server4CalcNumber";

	// IceAdapter name !!! The same as in config file !!!
	static String ADAPTER_NAME = "Adapter4CalcNumber";

	// Server menu commands

	// Exit command and shutdowhook
	public static class ShutdownTheServer extends Thread	{
		@Override
		public void run() {
			if (comm != null)	{
				System.out.println("SHUTDOWN begins ...");
				try	{
					comm.destroy();
				} catch (Exception ex)	{
					System.out.println("ON DESTROY: " + ex);
					System.exit(1);
				}
			}
		}

	}

	static Item AddCalc = new Item(
			"Create and register new CalcNumber instance (<string> instance name)", 
			new Action(){
				public String[] doAction(){
					String[] res = {"Enter the name of NumberCalc obj"};
					
					String inData = getInput();
					Scanner sc = new Scanner(inData);
					if (!sc.hasNext()) return res;
					String cName = sc.next();

					Identity servantId = new Identity(cName,ADAPTER_NAME);
					if (adapter.find(servantId)!=null)	{
						res = new String[]{"The name [" + cName + "] is used already.", "Try another name"};
						return res;
					}
					CalcNumber calcNumberImpl = new CalcNumberImpl(log);
					
					adapter.add(calcNumberImpl, servantId);
					String calcIndirectProxy = adapter.createProxy(servantId).ice_toString();
					String calcDirectProxy = adapter.createDirectProxy(servantId).ice_toString();
					
					res = new String[]{"IndirectProxy [" + calcIndirectProxy + "]", 
							"DirectProxy [" + calcDirectProxy + "]"};
					
					return res;
				}
			}
	);

	static Item RemoveCalc = new Item(
			"Remove CalcNumber instance by the name (<string> instance name)", 
			new Action(){
				public String[] doAction(){
					String[] res = {"Enter the name of NumberCalc obj"};
					
					String inData = getInput();
					Scanner sc = new Scanner(inData);
					if (!sc.hasNext()) return res;
					String cName = sc.next();
					Identity servantId = new Identity(cName,ADAPTER_NAME);
					
					if (adapter.find(servantId)==null)	{
						res = new String[]{"The name [" + cName + "] is unknown.", "Try another name"};
						return res;
					}
					
					adapter.remove(servantId);
					
					res = new String[]{"Servant [" + servantId.name + "." + servantId.category + "] removed"};
					
					return res;
				}
			}
	);


	@Override
	public int run(String[] arg0) {
		setInterruptHook(new ShutdownTheServer());
		comm = communicator();
		if (comm == null)	{
			System.out.println("Communicator is NULL...");
			return 1;
		}
		log = comm.getLogger();

		Map<String,String> icePropDict; 
		Set<String> keys;
		log.print("=============== Ice Server Config properties ===============");
		log.print("=== Ice.* ===");
		icePropDict = comm.getProperties().getPropertiesForPrefix("Ice");
		keys = icePropDict.keySet();
		for (String key : keys)
			log.print("" + key + "=" + icePropDict.get(key));

		log.print("=== Adapter* ===");
		icePropDict = comm.getProperties().getPropertiesForPrefix("Adapter");
		keys = icePropDict.keySet();
		for (String key : keys)
			log.print("" + key + "=" + icePropDict.get(key));

		log.print("=== Demo* ===");
		icePropDict = comm.getProperties().getPropertiesForPrefix("Demo");
		keys = icePropDict.keySet();
		for (String key : keys)
			log.print("" + key + "=" + icePropDict.get(key));

		log.print("============================================================");

		// Register Class at Communicator 
		MyNumberObjectFactory OF = new MyNumberObjectFactory();
		comm.addObjectFactory(OF, MyNumber.ice_staticId());
		comm.addObjectFactory(OF, MyNumberFloat.ice_staticId());
		comm.addObjectFactory(OF, MyNumberString.ice_staticId());

		adapter = communicator().createObjectAdapter(ADAPTER_NAME);
		log.print("Adapter activating...");
		adapter.activate();
		log.print("Done");
	
		communicator().waitForShutdown();
		return 0;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Item[] menuItems = {AddCalc, RemoveCalc};
		Action onExit = new Action(){
			public String[] doAction()	{
				String[] res = {"exit..."};
				System.exit(0);
				return res;
			}
		};

		final Menu menu = new Menu(System.in,System.out,menuItems);
		
		menu.setExitAction(onExit);
		
		new Thread(){ public void run(){menu.run();}}.start();

		IceServer4CalcNumber server = new IceServer4CalcNumber();
		int status = server.main(SERVER_APP_NAME, args);
		System.out.println(SERVER_APP_NAME + " stopped with status [" + status + "]");


	}

	{
		// For correct shutdown 
	}

}
